# coding: utf-8
from Tkinter import *
from abc import abstractmethod, ABCMeta
from ttk import *

from utils.ui_utils import LabelEntry, UICheckbutton, LabelCombobox
from utils.tool_utils import Config


class BaseFilter:
    __metaclass__ = ABCMeta

    def __init__(self, master):
        self.master = Frame(master)
        self.master.pack(side=TOP, fill=X)

    @abstractmethod
    def get_filter(self):
        return

    def destroy(self):
        self.master.destroy()


class LogFilter:
    def __init__(self, master):
        self.master = Frame(master)
        self.master.pack(side=TOP, fill=X)

        self.filter_class = None
        self.config = Config()

        self.filter_modes = ["General", "PP", "WDJ", "PPKV"]
        self.filter_mode = self.config.get("logcat", "mode")
        if self.filter_mode not in self.filter_modes:
            self.filter_mode = self.filter_modes[0]
        frm_mode = Frame(self.master)
        frm_mode.pack(side=TOP, anchor=W)
        self.cbb_filter_mode = LabelCombobox(frm_mode, label="过滤模式", values=self.filter_modes,
                                             command=self.select_filter_mode, default_value=self.filter_mode,
                                             state="readonly", width=12, )
        self.select_filter_mode()

        self.time_str_check = UICheckbutton(frm_mode, text="时间信息", checked=True)

    def get_filter(self):
        if self.time_str_check.get_checked():
            option_v = "-v time "
        else:
            option_v = "-v tag "
        return option_v + self.filter_class.get_filter()

    def select_filter_mode(self, *args):
        self.filter_mode = self.filter_modes[self.cbb_filter_mode.current()]
        self.config.set("logcat", "mode", self.filter_mode)
        if self.filter_class is not None:
            self.filter_class.destroy()
            self.filter_class = None
        self.filter_class = eval(self.filter_mode + "Filter(self.master)")

        print "switch filter mode to:", self.filter_mode


class GeneralFilter(BaseFilter):
    def __init__(self, master):
        BaseFilter.__init__(self, master)

        self.log_priortys = ["Verbose", "Debug", "Info", "Warn", "Error"]
        self.log_priorty = "Verbose"

        frm_input = Labelframe(self.master, text="Log Filter")
        frm_input.pack(side=TOP, expand=True, fill=X, pady=4)

        self.tag_entry = LabelEntry(frm_input, label="Tag")
        self.cbb_log_priorty = LabelCombobox(frm_input, label="Priorty : ", state="readonly", width=10,
                                             values=self.log_priortys, command=self.select_log_priorty)
        self.keyword_entry = LabelEntry(frm_input, label="keyword", default_text="(Rism|start_client)", width=30)

    def get_filter(self):
        tag = self.tag_entry.get_text()
        if len(tag):
            filter_tag = tag + ":" + self.log_priorty.upper()[0:1] + " *:S "
        else:
            filter_tag = "*:" + self.log_priorty.upper()[0:1] + " "
        keyword = self.keyword_entry.get_text()
        if len(keyword):
            # 此处必须实用-E模式，才能实用|实现或匹配；使用单引号才能避免`需要\转义
            filter_keyword = "| grep -E '%s'" % keyword
        else:
            filter_keyword = ""
        filter_str = filter_tag + filter_keyword
        return filter_str

    def select_log_priorty(self, *args):
        self.log_priorty = self.log_priortys[self.cbb_log_priorty.current()]
        print "switch log priorty to:", self.log_priorty


class PPFilter(BaseFilter):
    def __init__(self, master):
        BaseFilter.__init__(self, master)

        self.logtypes = ["", "pageview", "click", "event"]
        self.logtype = ""

        frm_pp = Labelframe(self.master, text="PP Log Filter")
        frm_pp.pack(side=TOP, expand=True, fill=X, pady=4)

        self.cbb_logtype = LabelCombobox(frm_pp, label="logtype : ", state="readonly", width=12,
                                         values=self.logtypes, command=self.select_logtype)
        self.keyword_entry = LabelEntry(frm_pp, label="keywork")
        self.f_check = UICheckbutton(frm_pp, text="含有f")
        self.f_entry = LabelEntry(frm_pp, label="f")

    def get_filter(self):
        if not self.f_check.get_checked():
            f_value = ""
        elif len(self.f_entry.get_text()) > 0:
            f_value = "f=" + self.f_entry.get_text() + ".*"
        else:
            f_value = "f=[^`].*"
        filter_str = "| grep -E 'PPStatLogger.*logtype=%s.*%s.*%s'" % (self.logtype, self.keyword_entry.get_text(), f_value)
        return filter_str

    def select_logtype(self, *args):
        self.logtype = self.logtypes[self.cbb_logtype.current()]
        print "switch logtype to:", self.logtype


# Todo: 扩展豌豆荚的logcat filter
class WDJFilter(BaseFilter):
    def __init__(self, master):
        BaseFilter.__init__(self, master)

        frm_pp = Labelframe(self.master, text="WDJ Log Filter")
        frm_pp.pack(side=TOP, expand=True, fill=X, pady=4)
        self.keyword_entry = LabelEntry(frm_pp, label="keywork")

    def get_filter(self):
        filter_str = "| grep -E 'LogReporter.*%s'" % (self.keyword_entry.get_text())
        return filter_str


class PPKVFilter(BaseFilter):
    def __init__(self, master):
        BaseFilter.__init__(self, master)

        self.logtypes = ["", "pageview", "click", "event"]
        self.logtype = ""

        frm_pp = Labelframe(self.master, text="PP KV Log Filter")
        frm_pp.pack(side=TOP, expand=True, fill=X, pady=4)

        self.cbb_logtype = LabelCombobox(frm_pp, label="logtype : ", state="readonly", width=12,
                                         values=self.logtypes, command=self.select_logtype)
        self.keyword_entry = LabelEntry(frm_pp, label="keywork")
        self.pub_check = UICheckbutton(frm_pp, text="显示公共字段")
        self.f_check = UICheckbutton(frm_pp, text="含有f")
        self.f_entry = LabelEntry(frm_pp, label="f")

    def get_filter(self):
        if not self.f_check.get_checked():
            f_value = ""
        elif len(self.f_entry.get_text()) > 0:
            f_value = "f=" + self.f_entry.get_text() + ".*"
        else:
            f_value = "f=[^`].*"
        filter_str = "| grep -E 'StatLogger.*logAsyncInteral.*logtype=%s.*%s.*%s'" % (self.logtype, self.keyword_entry.get_text(), f_value)
        return filter_str

    def select_logtype(self, *args):
        self.logtype = self.logtypes[self.cbb_logtype.current()]
        print "switch logtype to:", self.logtype
